home *** CD-ROM | disk | FTP | other *** search
/ SGI Freeware 1999 August / SGI Freeware 1999 August.iso / dist / fw_proftpd.idb / usr / freeware / lib / proftpd / doc / API.z / API
Encoding:
Text File  |  1999-04-16  |  11.5 KB  |  261 lines

  1. ProFTPD Application Programmer Interface
  2. -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  3.  
  4. NOTE: This API documentation ONLY applies to proftpd versions 1.1.5 and
  5. greater, wherein the module interface was significantly enhanced.
  6.  
  7. ProFTPD modules are designed to handle and respond to configuration
  8. directives (at startup), FTP commands sent over the control connection by
  9. FTP clients, and authentication requests.
  10.  
  11. Module are prioritized in the *inverse* order of which they were loaded.
  12. In other words, the last loaded module is the FIRST to receive calls for a
  13. particular configuration directive, ftp command or authentication request.
  14. This can be used to allow later loaded modules (higher priority) to
  15. (optionally) "override" lower priority modules.  Thus, load order of the
  16. modules can be VERY important.
  17.  
  18. Module handler functions are _always_ declared as:
  19.  
  20. MODRET    my_handler_func(cmd_rec *cmd);
  21.  
  22. In include/modules.h, MODRET is defined as 'static modret_t *'.  cmd_rec
  23. is a structure created by the engine and passed to the handler which
  24. contains all information regarding the command, etc.  modret_t is a
  25. special structure that is created by the handler and returned to the
  26. engine in order to tell the engine how to proceed.  There are a few macros
  27. in include/modules.h which allow the module programmer to easily create
  28. return structures.  The `cmd' argument to each macro is a pointer to
  29. the current module function's cmd_rec structure.
  30.  
  31. HANDLED(cmd)
  32.  - indicates that the handler properly handled the command, and that the
  33. engine should consider the command completed and continue processing.
  34. Note that if a module handler returns HANDLED, POST_CMD handlers
  35. will be called for the command (see below for handler types).
  36.  
  37. DECLINED(cmd)
  38.  - indicates that the engine should act as though the handler was never
  39. called and continue processing.  POST_CMD type handlers will NOT
  40. be called in this case.
  41.  
  42. ERROR(cmd)
  43.  - A protocol error occured.  POST_CMD type handlers are NOT
  44. called.
  45.  
  46. ERROR_MSG(cmd,numeric,message)
  47.  - Same as above, however the string composed of "numeric message" is sent
  48. to the client.  In the case of directive configuration handlers, the
  49. "numeric" argument is ignored, "message" is displayed to the user (or
  50. logged via syslog), and proftpd terminates.
  51.  
  52. ERROR_INT(cmd,n)
  53.  - Same as above, however this indicates a single integer numeric error.
  54. (Used only in authentication/mapping handlers [see mod_unixpw.c])
  55.  
  56. Handler Tables
  57. --------------
  58.  
  59. Each module can define up to three different handler tables (which are
  60. registered via the module structure).  These need not all be supplied.
  61. They are grouped by handler class:
  62.  
  63.   conftable[]:    For configuration directive handlers.
  64.   cmdtable[]:    For command handlers, including POST_CMD and PRE_CMD
  65.                 (see below)
  66.   authtable[]:    For authentication handlers.
  67.  
  68. The "conftable" is a structure which lists all configuration directive
  69. handlers for the module.
  70.  
  71. The "cmdtable" is a structure which lists all FTP command handlers for the
  72. module.  Each entry in this table contains a special "command type" field
  73. which determines the general 'type' of handler.  There are currently four
  74. types: CMD, PRE_CMD, and POST_CMD and LOG_CMD.  When proftpd receives a
  75. command for a client, it enters a five (eight?) step command->module
  76. cascading delivery process: 
  77.  
  78.   1. Call any PRE_CMD type handlers which match the special "*"
  79.       command wildcard
  80.   1a. Call any PRE_CMD type handlers which match the command.
  81.   2. Call any CMD type handlers which match the special "*"
  82.       command wildcard
  83.   2a. Call any CMD type handlers which match the command.
  84.   3. Call any POST_CMD type handlers which match the special "*"
  85.       command wildcard
  86.   3a. Call any POST_CMD type handlers which match the command.
  87.   4. Call any LOG_CMD type handlers which match the special "*" wildcard.
  88.   5. Call any LOG_CMD type handlers which match the command.
  89.  
  90. Further more, the return type of a particular command can allow or
  91. disallow further dispatching.  Rules:
  92.  
  93.   PRE_CMD:
  94.     1. If DECLINED is returned, all other PRE_CMD handlers are called.
  95.     2. If ERROR is returned, command handler dispatching stops completely.
  96.   CMD:
  97.     1. If DECLINED is returned, all other CMD handlers are called.
  98.     2. If ERROR is returned, command handler dispatching stops completely.
  99.   POST_CMD:
  100.     1. If ERROR is returned, the message (if any) is sent to syslog,
  101.        however because the CMD handler already executed, nothing further
  102.        can be done.
  103.     
  104. As you can no doubt see, this allows a higher priority module to
  105. "overload" a PRE_CMD handler for a particular command and allow/disallow
  106. the command as desired.
  107.  
  108. As a general rule of thumb, PRE_CMD handlers should check syntax/basic
  109. applicability of the command, while CMD type handlers should actually
  110. do the 'work'.  POST_CMD handlers generally handle any kind of cleanup,
  111. while LOG_CMD handlers handle logging successful completion of the
  112. command.
  113.  
  114. Responding to client requests in command handlers
  115. =================================================
  116.  
  117. There are two main ways to respond to a client command inside a command
  118. handler.  The first way is incompatible with other other handlers, and
  119. should only be used if the handler is about to terminate the current
  120. connection (and thus kill the child, usually with end_login()).  This
  121. first method, using one of the core functions outlined below, must be used
  122. because in the event that a handler is about to terminate proftpd, the
  123. internal response lists will never be processed by the proftpd engine.
  124.  
  125.   Method 1 (Use only in conjunction with end_login() or similar
  126.             termination)
  127.  
  128.     send_response(char *numeric, char *format, ...);
  129.       -- immediately sends the given response with the indicated numeric
  130.          to the client
  131.  
  132.     send_response_ml_start(char *numeric, char *format, ...);
  133.       -- starts a multiline ftp protocol with the given numeric
  134.  
  135.     send_response_ml(char *format, ...);
  136.       -- continues a multiline response using the numeric specified
  137.          in send_response_ml_start();
  138.  
  139.     send_response_ml_end(char *format, ...);
  140.       -- completes a multiline response
  141.  
  142.     send_response_async(char *numeric, char *format, ...);
  143.       -- send an asyncronous message to the client, this function is
  144.          suitable for use inside signal handlers
  145.  
  146. The second, and prefered, method of transmitting numeric + text message
  147. responses to clients is via the internal response chain.  Using this
  148. allows all handlers to add their own individual responses which will all
  149. be sent en masse after the command successfully completes (or fails).
  150.  
  151. Proftpd maintains two such chains, one response chain for success
  152. messages, and one for error messages.  However, when all handlers for a
  153. given command have been called, proftpd evaluates the final condition of
  154. the command.  If it has failed (caused by a handler returning one of the
  155. available ERROR* macros), all responses pending in the error response
  156. chain are sent.  If the command has successfully completed, the normal
  157. (success) response chain is sent.  If a command has neither completed
  158. successfully nor resulted in an error, proftpd assumes the command is
  159. invalid and informs the client appropriately.  Either way, once the
  160. "lifetime" of the command is over, and one (or none) of the response
  161. chains has been sent, BOTH chains are destroyed.
  162.  
  163.   Method 2 (using response chains)
  164.  
  165.     add_response(char *numeric, char *format, ...);
  166.       -- adds the given numeric + message to the end of the _success_
  167.          chain, to be sent if the command successfully completes.
  168.  
  169.     add_response_err(char *numeric, char *format, ...);
  170.       -- adds the given numeric + message to the end of the _error_
  171.          chain, to be sent if the command results in a final error.
  172.  
  173. As you can see, with method 2, there is no corresponding _ml* functions
  174. for multiline replies.  This is because proftpd automatically generates a
  175. multiline format reply if it detects that there are two or more responses
  176. with the same numeric waiting to be sent to the client.  In many cases,
  177. you may be writing a handler (post_cmd, for example) that neither cares
  178. nor specifically knows what numerics other handlers are using during their
  179. responses.  In this case, you can use the special R_DUP response numeric,
  180. which tells proftpd that your response should be _assumed_ to be part of a
  181. multiline response started by another handler.  For example, if the
  182. following add_response() calls were made from different modules:
  183.  
  184. module a:
  185.   add_response(R_200,"Command successfully completed.");
  186.  
  187. module b:
  188.   add_response(R_DUP,"Statistics for command '%s': none.",cmd->argv[0]);
  189.  
  190. module c:
  191.   add_response(R_DUP,"XFOO post_cmd handler ran.");
  192.  
  193. The final output sent to the client (assuming the command was successfully
  194. handled) would be (assuming your command is named 'XFOO'):
  195.  
  196. 200-Command successfully completed.
  197.  Statistics for command 'XFOO': none.
  198. 200 XFOO post_cmd handler ran.
  199.  
  200. Authentication Handlers
  201. =======================
  202.  
  203. Authentication handlers allow a module to provide (or overload)
  204. authentication, uid/gid to name and name to uid/gid mappings.
  205.  
  206. In order for a module to provide this functionality, it must export an
  207. authtable (via the module structure), and define one or more of the
  208. following handler "names" (authtable.name).
  209.  
  210. Each handler accepts data in the cmd structure and should return it's
  211. data in the modret->data field.  The core function mod_create_data()
  212. can create this data structure properly for return to the caller.
  213.  
  214. Defined 'names' are:
  215.  
  216. "setpwent"    : low-level emulation of setpwent libc function
  217. "setgrent"    : low-level emulation of setgrent libc function
  218. "endpwent"    : low-level emulation of endpwent libc function
  219. "endgrent"    : low-level emulation of endgrent libc function
  220. "getpwent"    : low-level emulation of getpwent libc function
  221. "getgrent"    : low-level emulation of getgrent libc function
  222. "getpwnam"    : low-level emulation of getpwnam libc function
  223. "getgrnam"    : low-level emulation of getgrnam libc function
  224. "getpwuid"    : low-level emulation of getpwuid libc function
  225. "getgrgid"    : low-level emulation of getgrgid libc function
  226. "auth"        : authenticate user
  227.                   (cmd->argv[0] = user,
  228.                    cmd->argv[1] = cleartext password)
  229. "check"        : compare supplied passwords
  230.           (cmd->argv[0] = hashed password,
  231.                    cmd->argv[1] = user,
  232.            cmd->argv[2] = cleartext password)
  233. "uid_name"    : map uid to name
  234.           (cmd->argv[0] = (char*)uid)
  235. "gid_name"    : map gid to group
  236.                   (cmd->argv[0] = (char*)gid)
  237. "name_uid"      : map name to uid
  238.                   (cmd->argv[0] = name)
  239. "name_gid"      : map group to gid
  240.                   (cmd->argv[0] = name)
  241.  
  242. The cascaded order of authentication handlers is similar to command
  243. handlers, but slightly different.  Rules:
  244.  
  245.   1. If an authentication handler returns DECLINED, handlers in other
  246.      modules are called (in priority load order, just as with command
  247.      handlers).  If ALL handlers for a particular function return
  248.      DECLINED, proftpd will assume that the operation failed.
  249.  
  250.   2. If an authentication handler returns HANDLED, proftpd assumes
  251.      that the operation completed successfully, and will stop calling
  252.      auth handlers.  Most auth handlers MUST return data if they complete
  253.      successfully (note that some void-style handlers do not have this
  254.      requirement; i.e. "setpwent" and friends).
  255.  
  256.   3. If an authentication handler returns ERROR, proftpd assumes an
  257.      error has occured and discontinues calling other handlers.  Some
  258.      functions ("auth", for example), should use the ERROR_INT macro
  259.      to return a numeric error code (one of the AUTH_* macros in
  260.      include/modules.h) indicating the reason for failure.
  261.